#include <netinet/in.h>
#include <arpa/inet.h>

#include "common.hpp"
#include "xfactory.hpp"
#include "xbroadcaster.hpp"

XFactory::removedlist_t XFactory::s_rlist;

size_t
XFactory::runRemove(void)
{
	size_t cnt(0);
	removedlist_t::iterator ib(s_rlist.begin());
	removedlist_t::iterator ie(s_rlist.end());

	PWFile* pfile;

	while ( ib != ie )
	{
		pfile = *ib;
		if ( pfile )
		{
			std::cerr << "destroy: " << pfile << std::endl;
			pfile->destroy();
			delete pfile;
		}

		++ib;
		++cnt;
	}

	s_rlist.clear();

	return cnt;
}

bool
XFactory::addRemovedList(PWFile* pfile)
{
	return s_rlist.insert(pfile).second;
}

bool
XFactory::open(const char* port)
{
	if ( !initialize(PF_INET, SOCK_STREAM, 0) )
	{
		cerr << "failed to init socket" << endl;
		return false;
	}

	do
	{
		PWSocketAddress addr;
		addr.setIP(PF_INET, "0.0.0.0", port);
		if ( !bind(addr) )
		{
			cerr << "failed to bind: " << port << endl;
			break;
		}

		if ( !listen(50) )
		{
			cerr << "failed to listen: " << port << endl;
			break;
		}

		getSocketName(addr);
		char lport[1024+1] = "";
		addr.getIP(NULL,NULL,lport);
		cerr << "port: " << lport << endl;

		return true;
	} while (false);

	destroy();
	return false;
}

void
XFactory::onEvent(PWIOPoll* io, int fd, int events)
{
	XBroadcaster* psock(new XBroadcaster);
	if ( !psock )
	{
		cerr << "not enough memory" << endl;
		return;
	}

	if ( !accept(psock) )
	{
		cerr << "failed to accept" << endl;
		psock->destroy();
		delete psock;
		return;
	}

	gPWFileUtil.setModeBlock(*psock, false);
	io->add(psock, PWIO_RW);

	PWSocketAddress addr;
	psock->getSocketName(addr);
	char ip[1024] = "";
	char port[1024] = "";
	addr.getIP(NULL, ip, port);
}

